package com.cloudspace.jindun.websocket;

/**
 * Created by zengxianhua on 17/1/24.
 */

/**
 * $Id$
 * Copyright 2009-2012 Oak Pacific Interactive. All rights reserved.
 */

import android.text.TextUtils;

import com.cloudspace.jindun.ext.aq.AQUtility;
import com.cloudspace.jindun.log.APPLog;
import com.cloudspace.jindun.utils.StringUtil;

import de.tavendo.autobahn.WebSocket;
import de.tavendo.autobahn.WebSocketConnection;
import de.tavendo.autobahn.WebSocketConnectionHandler;
import de.tavendo.autobahn.WebSocketException;

public class WebSocketManager {

    private static final String TAG = WebSocketManager.class.getSimpleName();

    private static WebSocketManager mInstance = new WebSocketManager();

    private WebSocket mConnection = new WebSocketConnection();

    private IWebSocketListener mListener;

    private boolean mIsPingStarted = false;

    protected HeartRunnabler mHeartRunnabler = new HeartRunnabler();

//    public static final int HEART_PING_TIME = 15 * 1000; //MS

    private int mPingFrequency;

    private WebSocketManager() {

    }

    public static WebSocketManager getInsatance() {
        return mInstance;
    }

    public boolean isConnected() {
        return mConnection != null && mConnection.isConnected();
    }

    public void setListener(IWebSocketListener l) {
        mListener = l;
    }

    public synchronized void connect(String wsuri) throws Exception {
        mIsPingStarted = false;
        log("connect wsuri is " + wsuri);
        try {
            closeByUser();
            mConnection = new WebSocketConnection();
            log("connect wsuri is init ok---");
            //      尝试打开连接
            mConnection.connect(wsuri, new WebSocketConnectionHandler() {

                @Override
                public void onOpen() {
                    log("connect wsuri is onOpen");
                    if (mListener != null) {
                        mListener.open();
                    }
                }

                @Override
                public void onClose(int code, String reason) {
                    log("connect wsuri is onClose." + " code:" + code + "    reason:" + reason);
                    if (!TextUtils.isEmpty(reason) && mListener != null) {
                        mListener.error(code, reason);
                    }
                }

                @Override
                public void onTextMessage(String payload) {
                    log("connect wsuri is onTextMessage " + payload);// + "  payload :" + payload);
                    WebSocketMessageController.getInstance().onReceiveMessage(payload);
                }

                @Override
                public void onBinaryMessage(byte[] payload) {
                    log("connect wsuri is onBinaryMessage");// + "  payload :" + payload);
                }

                @Override
                public void onRawTextMessage(byte[] payload) {
                    log("connect wsuri is onRawTextMessage");// + "  payload :" + payload);

                }

            });
        } catch (WebSocketException e) {
            //捕获WebSocketException 连接异常
            e.printStackTrace();
            log("connect init WebSocketException:" + e.getMessage());
            if (mListener != null) {
                mListener.error(WebSocket.ConnectionHandler.CLOSE_CANNOT_CONNECT, e.getMessage());
            }
        }

    }

    public synchronized void closeByUser() {
        if (mConnection != null) {
            mConnection.disconnect(0);
            mConnection = null;
        }
    }

    public void releaseListener() {
        mListener = null;
    }

    public void sendExitRoomMessage(String txt) {
        if (!isConnected()) {
            return;
        }
        log("---sendExitRoomMessage--");//txt:" + txt);
        mConnection.sendTextMessage(txt);
    }

    public void sendTextMessage(String txt) {
        String signa = StringUtil.getMD5Hex(txt + "secretkey");
        txt = txt.substring(0, txt.length() - 1) + ",\"signature\":\"" + signa + "\"}";
        if (!isConnected()) {
            log("---sendTextMessage--socket is closed----");
            if (mListener != null) {
                mListener.error(-1, "socekt is closed");
            }
            return;
        }

        log("---sendTextMessage--txt:" + txt);
        mConnection.sendTextMessage(txt);
    }

    private void sendPing() {
        APPLog.v("ping", "--websocketManager---sendPing-----");
        if (!isConnected()) {
            if (mListener != null) {
                mListener.error(-1, "socekt is closed");
            }
            return;
        } else {
            try {
                mConnection.sendPing();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public void startPing(int ping) {
        if (ping <= 0) {
            return;
        }
        mPingFrequency = ping;
        APPLog.v("ping", "-----startPing------mIspingstarted----" + mIsPingStarted);
        if (!mIsPingStarted) {
            mIsPingStarted = true;
            AQUtility.post(mHeartRunnabler);
        }
    }

    public void closePing() {
        mIsPingStarted = false;
        APPLog.v("ping", "-----closePing------");
        AQUtility.getHandler().removeCallbacks(mHeartRunnabler);
    }

    private void log(String s) {
        APPLog.zxhLog(TAG + " " + s);
    }

    public interface IWebSocketListener {

        void open();

        void error(int errorCode, String errorMessage);
    }

    //心跳线程 10s

    public class HeartRunnabler implements Runnable {

        @Override
        public void run() {
            sendPing();
            AQUtility.getHandler().postDelayed(mHeartRunnabler, mPingFrequency * 1000);
        }

    }

}

